package com.liu.project.kmeans;



import com.liu.project.pojo.Certificate;
import com.liu.project.service.CertificateService;
import com.liu.project.utils.RedisUtil;
import com.liu.project.utils.UserUtil;
import com.mysql.cj.jdbc.MysqlDataSource;

import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.common.Weighting;
import org.apache.mahout.cf.taste.eval.RecommenderBuilder;

import org.apache.mahout.cf.taste.impl.model.jdbc.MySQLJDBCDataModel;
import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.model.JDBCDataModel;
import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
import org.apache.mahout.clustering.Model;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;


import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 创建数据模型 —> 用户相似度算法 —>用户近邻算法 —>推荐算法。
 * 　　基于用户的协同过滤算法在Mahout库中已经模块化了，
 * 通过4个模块进行统一的方法调用。首先，创建数据模型(DataModel)，
 * 然后定义用户的相似度算法(UserSimilarity)，
 * 接下来定义用户近邻算法(UserNeighborhood )，
 * 最后调用推荐算法(Recommender)完成计算过程。
 * 而基于物品的协同过滤算法(ItemCF)过程也是类似的，去掉第三步计算用户的近邻算法就行了。
 */

/**
 * DataModel：用于存储 用户、项目 和 首选项
 * UserSimilarity：用于定义两个用户之间的相似度的界面
 * ItemSimilarity：用于定义两个项目之间的相似度的界面
 * Recommender：用于提供推荐的界面
 * UserNeighborhood：用于计算相似用户邻近度的界面，其结果随时可由 Recommender 使用
 */
@Service
public class UserBased2 {


    @Autowired
    CertificateService service;

    final static int NEIGHBORHOOD_NUM = 4;//临近用户数量
    final static int RECOMMENDER_NUM = 5;//推荐物品数量


    String url = "jdbc:mysql://localhost:3306/project2?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false";

    String username = "root";

    String password = "123456";

    public List<Integer> UserBased2(int userId) throws TasteException {

        MysqlDataSource dataSource = new MysqlDataSource();
        dataSource.setUrl(url);
        dataSource.setUser(username);
        dataSource.setPassword(password);
        JDBCDataModel dataModel = new MySQLJDBCDataModel(dataSource, "view_log", "userId", "param", "pf",null);


        DataModel model = dataModel;
        RecommenderBuilder recommenderBuilder = new RecommenderBuilder() {
            @Override
            public Recommender buildRecommender(DataModel model) throws TasteException {
                UserSimilarity similarity = new PearsonCorrelationSimilarity(model, Weighting.WEIGHTED);
                UserNeighborhood userNeighborhood = new NearestNUserNeighborhood(NEIGHBORHOOD_NUM, similarity, model);
                return new GenericUserBasedRecommender(model, userNeighborhood, similarity);
            }
        };
        List<RecommendedItem> recommendations = recommenderBuilder.buildRecommender(model).recommend(userId, RECOMMENDER_NUM);
        System.out.printf("uid:%s", userId);
        List list = new ArrayList<>();
        for (RecommendedItem recommendation : recommendations) {
            System.out.printf("(%s,%f)", recommendation.getItemID(), recommendation.getValue());
            Certificate certificateById = service.findCertificateById((int) recommendation.getItemID());
            list.add(certificateById);
        }
        System.out.println();

        return list;
    }


}